package com.akbar.service.impl;

import com.akbar.constant.JwtClaimsConstant;
import com.akbar.dto.LoginDto;
import com.akbar.entity.SysUser;
import com.akbar.properties.JwtProperties;
import com.akbar.security.SecurityUser;
import com.akbar.service.AuthService;
import com.akbar.utils.JwtUtil;
import com.akbar.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public UserVo login(LoginDto loginDto) {

        // 封装认证信息
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword());

        // 调用认证管理器认证，返回认证后的 Authentication
        Authentication authentication = authenticationManager.authenticate(authenticationToken);

        // 从 Authentication 中获取 SecurityUser
        SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
        SysUser sysUser = securityUser.getSysUser();

        // 提取角色
        List<String> roles = securityUser.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .filter(auth -> auth.startsWith("ROLE_"))
                .map(auth -> auth.substring(5)) // 去掉 ROLE_ 前缀
                .toList();

        // 提取权限
        List<String> permissions = securityUser.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .filter(auth -> !auth.startsWith("ROLE_"))
                .toList();

        // 生成jwt token
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USERNAME, sysUser.getUsername());
        claims.put(JwtClaimsConstant.USER_ID, sysUser.getId());
        String token = jwtUtil.generateToken(claims);

        // 把token存储到redis中
        redisTemplate.opsForValue()
                .set(
                        token,
                        token,
                        jwtProperties.getExpiration(),
                        TimeUnit.MILLISECONDS
                );

        return UserVo.builder()
                .id(sysUser.getId())
                .username(sysUser.getUsername())
                .email(sysUser.getEmail())
                .phone(sysUser.getPhone())
                .realName(sysUser.getRealName())
                .avatar(sysUser.getAvatar())
                .userType(sysUser.getUserType())
                .token(token)
                .roles(roles)
                .permissions(permissions)
                .build();
    }
}
